package com.gitee.webdav.kernel;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.NioUtil;
import cn.hutool.core.io.file.FileMode;
import com.google.auto.service.AutoService;
import lombok.extern.slf4j.Slf4j;
import org.smartboot.http.common.io.BufferOutputStream;
import org.smartboot.http.server.HttpResponse;

import java.io.File;
import java.io.InputStream;
import java.io.RandomAccessFile;

/**
 * @author hongda.li@hand-china.com
 */
@Slf4j
@AutoService(ResourceReadonlyHandler.class)
public class ResourceDownloader extends ResourceHeader {

    @Override
    protected MethodEnum method() {
        return MethodEnum.GET;
    }

    @Override
    protected void downloadAll(HttpResponse response, File file) {
        try (InputStream stream = FileUtil.getInputStream(file)) {
            stream.transferTo(response.getOutputStream());
            log.info("全量读取完成 : {}", FileUtil.getName(file));
        } catch (Exception e) {
            log.warn("全量读取中断 : {}", e.getMessage());
        }
    }

    @Override
    protected void downloadPart(HttpResponse response, File file, Range range) {
        @Remark("缓冲区大小")
        int bufferSize = (int) Math.min(range.end() - range.start() + 1, NioUtil.DEFAULT_MIDDLE_BUFFER_SIZE);

        @Remark("读取指定位置的文件数据")
        BufferOutputStream stream = response.getOutputStream();
        try (RandomAccessFile raf = FileUtil.createRandomAccessFile(file, FileMode.r)) {
            raf.seek(range.start());
            byte[] data = new byte[bufferSize];
            while (true) {
                int read = raf.read(data);
                if (read == -1) {
                    break;
                }
                stream.write(data, 0, read);
            }
            log.info("断点续传完成 : {}", range);
        } catch (Exception e) {
            log.warn("断点续传中断 : {}", e.getMessage());
        }
    }
}
